package com.neusoft.tijian.service.impl;

import com.neusoft.tijian.dto.CalendarRequestDto;
import com.neusoft.tijian.dto.CalendarResponseDto;
import com.neusoft.tijian.dto.OrdersMapperDto;
import com.neusoft.tijian.mapper.HospitalMapper;
import com.neusoft.tijian.mapper.OrdersMapper;
import com.neusoft.tijian.service.CalendarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

@Service
public class CalendarServiceImpl implements CalendarService {

    @Autowired
    private HospitalMapper hospitalMapper;

    @Autowired
    private OrdersMapper ordersMapper;

    /**
     * 生成预约日期
     *
     * @param calendarRequestDto
     * @return
     */
    @Override
    public List<CalendarResponseDto> listAppointmentCalendar(CalendarRequestDto calendarRequestDto) {
        // 获取预约日期列表
        List<CalendarResponseDto> calendarList30 = getCalendarList30(calendarRequestDto.getHpId());
        // 获取当前日历
        List<CalendarResponseDto> currentCalendarList = getCurrentCalendarList(calendarRequestDto.getYear(), calendarRequestDto.getMonth());
        // 给当前日历填充属性
        for (CalendarResponseDto current: currentCalendarList) {
            for (CalendarResponseDto calendar: calendarList30) {
                if (current.getYmd() != null) {
                    if (current.getYmd().equals(calendar.getYmd())) {
                        current.setTotal(calendar.getTotal());
                        current.setExisting(calendar.getExisting());
                        current.setRemainder(calendar.getRemainder());
                    }
                }
            }
        }
        return currentCalendarList;
    }

    /**
     * 获取 30 天预约日期列表
     */
    private List<CalendarResponseDto> getCalendarList30(Integer hpId) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();

        // 做一个临时合集，做为去 Orders 表中查询的参数
        List<OrdersMapperDto> paramList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            OrdersMapperDto dto = new OrdersMapperDto();
            // 计算 1 天后的时间
            calendar.add(Calendar.DATE, 1);
            dto.setDate(sdf.format(calendar.getTime()));
            dto.setHpId(hpId);
            paramList.add(dto);
        }

        // 根据 paramList 参数，查询 30 天预约日期中，每一天的已预约人数
        // 查询结果 CalendarResponseDto 中只有两个属性：ymd, existing，还有两个属性需要填充：total, remainder
        List<CalendarResponseDto> calendarList30 = ordersMapper.listOrdersAppointmentNumber(paramList);

        // 根据医院编号，获取预约规则
        String[] strArr = hospitalMapper.getHospitalById(hpId).getRule().split(",");

        // 继续填充 calendarList30 返回值中的 total, remainder 属性
        for (CalendarResponseDto cd : calendarList30) {
            // 将预约日期转换为 Calendar 对象
            try {
                calendar.setTime(sdf.parse(cd.getYmd()));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            int total = Integer.parseInt(strArr[calendar.get(Calendar.DAY_OF_WEEK) - 1]);
            // 填充
            cd.setTotal(total);
            cd.setRemainder(total - cd.getExisting());
        }
        return calendarList30;
    }

    /**
     * 获取当前年和月的日历
     */
    private List<CalendarResponseDto> getCurrentCalendarList(Integer year, Integer month) {
        List<CalendarResponseDto> currentCalendar = new ArrayList<>();

        // 做万年历
        boolean isRun = false;
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
            isRun = true;
        }
        // 计算从 1900-01-01 到现在的天数
        int totalDays = 0;
        for (int i = 1900; i < year; i++) {
            if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0)) {
                totalDays += 366;
            } else {
                totalDays += 365;
            }
        }
        int beforeDays = 0;
        int currentDays = 0;
        for (int j = 1; j < month; j++) {
            switch (j) {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    currentDays = 31;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    currentDays = 30;
                    break;
                case 2:
                    if (isRun) {
                        currentDays = 29;
                    } else {
                        currentDays = 28;
                    }
                    break;
            }
            if (j < month) {
                beforeDays += currentDays;
            }
        }
        totalDays += beforeDays;
        int firstDayOfMonth = totalDays % 7 + 1;
        if (firstDayOfMonth == 7) {
            firstDayOfMonth = 0;
        }
        for (int k = 0; k < firstDayOfMonth; k++) {
            currentCalendar.add(new CalendarResponseDto());
        }
        for (int i = 1; i <= currentDays; i++) {
            String m = month < 10 ? "0" + month : String.valueOf(month);
            String d = i < 10 ? "0" +i : String.valueOf(i);
            currentCalendar.add(new CalendarResponseDto(year + "-" + m + "-" + d));
        }
        return currentCalendar;
    }

}
